<?php
/**
 * Created by PhpStorm.
 * User: Bixue
 * Date: 18-9-14
 */
namespace app\workerman\model;
use \GatewayWorker\Lib\Gateway as Client;
use app\common\model\Kline as K;
use app\common\model\Quotation as Q;
use think\Db;

class Kline
{
    const TAB_NAME       = "kline";
    const TAB_NAME_TRADE = "trade";
    const TAB_NAME_ORDER = "order";

    /**
     * addKline
     * @author 王海东
     * @date
     * @deprecated 设置1分钟1天k线图
     * @param $interval
     * @return bool
     */
    public function  addKline($interval)
    {
        $trade = Db(self::TAB_NAME_TRADE, [], false)
            ->where(['available' => '1'])
            ->whereNull('delete_time')
            ->select();

        foreach ($trade as $key => $val)
        {
            if($interval == '1m') {
                $prefix = config('database.prefix');

                $date = date('Y-m-d H:i');

                $sql = "select max(expected_price) as max , min(expected_price) as min from {$prefix}order where DATE_FORMAT(trading_time, '%Y-%m-%d %H:%i') = '{$date}' and status = 3 and trade_id = '{$val['id']}' order by id desc limit 1";

                $order = Db::query($sql);

                $max = $order[0]['max'];
                $min = $order[0]['min'];
            } else {

                if(date('H') !== '00')  //每天凌晨00点计算k线图
                    return false;

                $order = Db(self::TAB_NAME_ORDER, [], false)
                    ->field('max(expected_price) as max , min(expected_price) as min')
                    ->where(['status' => 3,'trade_id' => $val['id']])
                    ->whereTime('trading_time','yesterday')
                    ->find();

                $max = $order['max'];
                $min = $order['min'];
            }


            if(!empty($max) && !empty($min)) {

                $kline = Db(self::TAB_NAME, [], false)
                    ->field('id,time')
                    ->where(['trade_id' => $val['id'],'interval_v' => $interval])
                    ->order('id desc')
                    ->find();

                $close = Db(self::TAB_NAME, [], false)
                    ->where(['trade_id' => $val['id'],'interval_v' => $interval])
                    ->where('id','neq',$kline['id'])
                    ->order('id desc')
                    ->value('close');

                if(!empty($close)) {
                    $open   = $close;
                    $close  = $val['last_trading_price'];
                } else {
                    $open   = $val['last_trading_price'];
                    $close  = $val['last_trading_price'];
                }

                $high   = $max;
                $low    = $min;

                if(!empty($open)) {
                    $dataArr['high']        = $high;
                    $dataArr['low']         = $low;
                    $dataArr['close']       = $close;
                    $dataArr['open']        = $open;
                    $dataArr['trade_id']    = $val['id'];
                    $dataArr['time']        = date('Y-m-d H:i');
                    $dataArr['interval_v']  = $interval;

                    if($interval == '1m') {
                        $date = date('Y-m-d H:i');
                        if(strtotime($kline['time']) != strtotime($date)) $status = 1;
                        else $status = 0;
                    } else {
                        $date = date('Ymd');
                        if(strtotime(date('Ymd',strtotime($kline['time']))) != strtotime($date)-86400)    $status = 1;
                        else $status = 0;

                        $dataArr['time'] = date('Y-m-d',strtotime('-1day'));
                    }

                    if($status == 1) {
                        $dataArr['create_time'] = date('Y-m-d H:i');
                        Db(self::TAB_NAME, [], false)->insert($dataArr);
                    } else {
                        Db(self::TAB_NAME, [], false)->where('id',$kline['id'])->update($dataArr);
                    }
                }
            }
        }
    }

    /**
     * weekKline
     * @author 王海东
     * @date
     * @deprecated  设置一周k线图
     * @return void
     */
    public function weekKline()
    {
        $trade = Db(self::TAB_NAME_TRADE, [], false)
            ->where(['available' => '1'])
            ->whereNull('delete_time')
            ->select();

        foreach ($trade as $key => $val)
        {
            $kline = Db(self::TAB_NAME, [], false)
                ->field("count(*) count,group_concat(id) idStr,DATE_FORMAT(time,'%Y%u') weeks")
                ->where(['trade_id' => $val['id'],'interval_v' => '1d'])
                ->group('weeks')
                ->select();

            $data = array();
            foreach ($kline as $k => $v)
            {
                $lastData   = db(self::TAB_NAME, [], false)
                    ->field('close,time,open,trade_id')
                    ->where("id in({$v['idStr']})")
                    ->select();

                $Hl         = db(self::TAB_NAME, [], false)
                    ->field('max(high) high,min(low) low')
                    ->where("id in ({$v['idStr']})")
                    ->find();

                $trade_id       = $lastData[0]['trade_id'];
                $close          = $lastData[$v['count']-1]['close'];
                $open           = $lastData[0]['open'];
                $time           = $lastData[$v['count']-1]['time'];

                $data[$k]['open']           = (float) $open;
                $data[$k]['high']           = (float) $Hl['high'];
                $data[$k]['low']            = (float) $Hl['low'];
                $data[$k]['close']          = (float) $close;
                $data[$k]['trade_id']       = (string) $trade_id;
                $data[$k]['interval_v']     = (string) '1w';
                $data[$k]['time']           = (string) $time;
                $data[$k]['create_time']    = (string) date('Y-m-d H:i');
            }

            $klineCount = Db(self::TAB_NAME, [], false)
                ->where(['interval_v' => '1w','trade_id' => $val['id']])
                ->count();

            if($klineCount < count($data))
                Db(self::TAB_NAME, [], false)->insertAll($data);
        }
    }


    /**
     * fiveMinutes
     * @author 王海东
     * @date
     * @param $interval
     * @param $rows
     * @deprecated 设置 5，13,30,1hK线图数据
     * @return void
     */
    public function fiveMinutes($interval,$rows)
    {
        $trade = Db(self::TAB_NAME_TRADE, [], false)
            ->field('id')
            ->where(['available' => '1'])
            ->whereNull('delete_time')
            ->select();

        foreach ($trade as $key => $val) {

            $kline = Db(self::TAB_NAME, [], false)
                ->where(['interval_v' => '1m','trade_id' => $val['id']])
                ->select();

            $count  = count($kline);
            $c      = 0;

            $datas  = array();

            for ($i=0; $i <$count ; $i++) {
                $datas[] = array_slice($kline,$c,$rows);
                $c += $rows;
            }

            $datas = array_filter($datas);

            $kData = array();

            for ($i = 0; $i < count($datas); $i++) {

                $sell_count = count($datas[$i]);

                if($sell_count < $rows)
                    continue;

                $time   = $datas[$i][$sell_count-1]['time'];
                $open   = $datas[$i][0]['open'];
                $close  = $datas[$i][$sell_count-1]['close'];

                $high   = array();
                $low    = array();

                for ($l = 0;$l < $sell_count;$l++) {
                    $high[] = $datas[$i][$l]['high'];
                    $low[]  = $datas[$i][$l]['low'];
                }

                $kData[$i]['time']          = $time;
                $kData[$i]['open']          = $open;
                $kData[$i]['close']         = $close;
                $kData[$i]['high']          = max($high);
                $kData[$i]['low']           = min($low);
                $kData[$i]['interval_v']    = $interval;
                $kData[$i]['trade_id']      = $datas[$i][0]['trade_id'];
                $kData[$i]['create_time']   = date('Y-m-d H:i');
            }

            $klineCount = Db(self::TAB_NAME, [], false)
                ->where(['interval_v' => $interval,'trade_id' => $val['id']])
                ->count();

            if($klineCount < count($kData))
                Db(self::TAB_NAME, [], false)->insertAll($kData);
        }
    }




    /**
     * getKline
     * @author 王海东
     * @deprecated 获取k线并推送
     * @deprecated hangqing_ 为k线图,fenshi_ 为分时折线图
     * @return void
     */
    public function getKline()
    {
        $interval = ['1m','3m','5m','10m','15m','30m','60m','1d','1w'];

        $trade = db(self::TAB_NAME_TRADE,[],false)
                   ->where('available',1)
                   ->whereNull('delete_time')
                   ->column('id');

        Client::$registerAddress = '127.0.0.1:8201';

        foreach ($trade as $key => $val) {

            //K线图
            foreach ($interval as $k => $v) {
                $k   = new K();
                $kData = $k->getList($val,null,$v,60);

                if($kData[0]) {
                    $message = json_encode(array('list' => $kData,'type' => 'hangqing'));
                    Client::sendToGroup('hangqing_'.$val,$message);
                }
            }

            //分时图
            $q = new Q();
            $qData = $q->getList($val);

            if($qData) {
                $message = json_encode(array('list' => $qData,'type' => 'fenshi'));
                Client::sendToGroup('hangqing_'.$val,$message);
            }
        }
    }
}